home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- * puzzle.c: This QNX Windows program creates a
- * moving tile puzzle, with 15 numbered tiles in a
- * 4 X 4 enclosure.
- *
- * It is reproduced here by permission of Quantum Software Systems, Ltd
- * of Kanata, Canada.
- */
-
- #include <stdio.h>
- #include <windows.h>
-
-
- #define RECT_HEIGHT 250
- #define RECT_WIDTH 360
- #define PANE_BORDER 140
-
- #define PANE_HEIGHT ((rows)*RECT_HEIGHT + 120)
- #define PANE_WIDTH ((rows)*RECT_WIDTH + 120)
- #define CASE(str) (((str)[0] << 8) | (str)[1])
-
- EVENT_MSG msg;
-
- int rows = 4, max_num;
- int b[20][20], old[20][20];
- int mv;
-
- èmain()
- {
- int go = YES, wid, pid;
-
- /* connect to QWindows */
- if ( !GraphicsOpen (NULL) )
- exit ( -1 );
-
- SetName("Puzzle", NULL); /* Optional */
-
- pid = PictureOpen ( "pict", NULL, NULL, LIGHT_GRAY, NULL, NULL, NULL );
- PictureHighlightOptions( NULL, 'N', 0, 0 );
-
- init();
- display();
-
- wid = WindowOpen ("Puzzle", PANE_HEIGHT, PANE_WIDTH,
- "MT480-r;s", NULL, NULL, pid);
-
- /*
- * Put control button in top frame.
- */
-
- WindowBarCurrent( TOP, NULL );
- SetButton( NULL, WHITE, NULL );
- DrawAt( 300, 120 );
- AttachDialog("Options", NULL,
- "Scramble;Size|@(Easy|03;The Famous 4 x 4|04;Hard|05;Very Hard|06;You've got to be Kidding|10)^R",
- NULL, "MD", NULL, NULL);
- DrawButton( "Options", NULL, "Ns;D", "op");
- Draw();
- WindowBarCurrent( NULL, NULL );
-
- load_icon( "/windows/apps/puzzle" );
-
- DrawStart(NULL, 0);
-
- while ( go )
- {
- GetEvent ( 0, &msg, sizeof(msg));
-
- switch ( Event ( &msg ) )
- {
- case QUIT:
- WindowClose( 0, NULL );
- go = NO;
- break;
-
- case TERMINATED:
- go = NO;
- break;
-
- case CLICK:
- if (msg.hdr.code == 'S') {
- /* game piece selected */è move(atoi(msg.hdr.key) - 1);
- mv++;
- win ();
- }
-
- break;
-
- case DIALOG:
- switch(CASE(msg.hdr.key)) {
- case '03': case '04': case '05': case '06':
- case '07': case '10':
- rows = atoi(msg.hdr.key);
- case 'Sc':
- new_game();
- break;
- }
- }
- }
-
- GraphicsClose( );
- exit (0);
- }
-
- init() {
- int i, j, r, loop;
-
- max_num = rows*rows;
-
- for (i = 0; i < rows; i++)
- for (j = 0; j < rows; j++) {
- b[i][j] = ( i * rows + j);
- old[i][j] = -1;
- }
-
- i = j = rows - 1;
- srand(get_ticks());
- r = rand() % 200 + 500;
-
- for (loop = 0; loop < 5000; ++loop) {
- switch (rand() % 4) {
- case 0:
- if (i != 0) {
- b[i][j] = b[i - 1][j];
- b[i - 1][j] = max_num;
- --i;
- }
- break;
-
- case 1:
- if (i != rows - 1) {
- b[i][j] = b[i + 1][j];
- b[i + 1][j] = max_num;
- i++;
- }
- break;
- è case 2:
- if (j != 0) {
- b[i][j] = b[i][j - 1];
- b[i][j - 1] = max_num;
- --j;
- }
- break;
-
- case 3:
- if (j != rows - 1) {
- b[i][j] = b[i][j + 1];
- b[i][j + 1] = max_num;
- j++;
- }
- break;
- }
- }
- }
-
-
-
- display() {
- int i, j;
-
- for (i = 0; i < rows; i++)
- if (memcmp(b[i], old[i], rows)) {
- for (j = 0; j < rows; j++)
- if (b[i][j] != max_num)
- draw_number(i, j, b[i][j] + 1);
- memcpy(old[i], b[i], rows);
- }
- }
-
-
- draw_number( row, col, number)
- int row, col, number;
- {
- char tbuf[4];
-
- tsprintf(tbuf, "%2d", number);
-
- SetColor ( "T", BLACK );
-
- DrawAt (PANE_BORDER + (row*RECT_HEIGHT) + CHARH/2,
- PANE_BORDER + (col*RECT_WIDTH ));
-
- DrawText( tbuf, 0, 0, 0, "Sem", tbuf);
-
- Draw ( );
- }
-
-
-
-
- move_number( row, col, number)èint row, col, number;
- {
- char buffer[7];
-
- tsprintf(buffer, "%2d", number);
- ShiftTo( buffer, PANE_BORDER + (row*RECT_HEIGHT) + CHARH/2,
- PANE_BORDER + (col*RECT_WIDTH ));
- }
-
-
-
- move(m)
- int m;
- {
- int i1, j1, i, j, i2, j2, c;
-
- i1 = j1 = -1;
-
- for (i = 0; i1 == -1 && i < rows; i++)
- for (j = 0; j < rows; j++)
- if (b[i][j] == m) {
- i1 = i;
- j1 = j;
- break;
- }
-
- if (i1 != -1) {
- i2 = j2 = -1;
- for (i = 0; i < rows; i++)
- if (b[i][j1] == max_num) {
- i2 = i;
- j2 = j1;
- break;
- }
- if (i2 == -1)
- for (j = 0; j < rows; j++)
- if (b[i1][j] == max_num) {
- i2 = i1;
- j2 = j;
- break;
- }
- if (i2 == -1)
- return;
- }
- else
- return;
-
- /* Hold picture for smoother updates */
- PictureHold( );
-
- if (i1 == i2)
- if (j1 < j2)
- for (j = j2 - 1; j >= j1; --j) {
- b[i1][j + 1] = b[i1][j];
- move_number(i1, j+1, b[i1][j]+1);è }
- else
- for (j = j2; j < j1; j++) {
- b[i1][j] = b[i1][j + 1];
- move_number(i1, j, b[i1][j+1]+1);
- }
- else
- if (i1 < i2)
- for (i = i2 - 1; i >= i1; --i) {
- b[i + 1][j1] = b[i][j1];
- move_number(i+1, j1, b[i][j1]+1);
- }
- else
- for (i = i2; i < i1; i++) {
- b[i][j1] = b[i + 1][j1];
- move_number(i, j1, b[i+1][j1]+1);
- }
- b[i1][j1] = max_num;
-
- /* update current picture */
- PictureContinue( );
- }
-
-
-
- win() {
- int c = 0, i, j;
- char buf[50];
-
- for (i = 0; i < rows; i++)
- for (j = 0; j < rows; j++)
- if (b[i][j] < c)
- return( 0 );
- else
- c = (int) b[i][j];
-
- tsprintf(buf, "You got it in %d moves!", mv);
- Notice( NULL, "You Win", NULL, "W", buf);
-
- return( 1 );
- }
-
-
- new_game() {
- RECT_AREA area;
-
- WindowInfo(NULL,&area,NULL,NULL,NULL,NULL);
-
- /* erase all elements in the picture */
- WindowHold( );
- Erase( ALL );
-
- area.height = PANE_HEIGHT;
- area.width = PANE_WIDTH;
- è init( );
- display( );
- mv = 0;
-
- WindowChange( &area, NULL, KEEP, NULL, "!" );
- WindowContinue( );
- }
-
-